// /**
//  * @author zhangshihao
//  * @create 2023-09-03 11:41
//  */
//
// import cn.hutool.http.HttpUtil;
// import cn.hutool.json.JSONArray;
// import cn.hutool.json.JSONObject;
// import com.fasterxml.jackson.databind.ObjectMapper;
// import com.ujs.oss.ServiceOssApplication;
// import org.apache.http.HttpEntity;
// import org.apache.http.client.methods.CloseableHttpResponse;
// import org.apache.http.client.methods.HttpPost;
// import org.apache.http.entity.ContentType;
// import org.apache.http.entity.mime.MultipartEntityBuilder;
// import org.apache.http.impl.client.CloseableHttpClient;
// import org.apache.http.impl.client.HttpClients;
// import org.apache.http.util.EntityUtils;
// import org.junit.Test;
// import org.junit.runner.RunWith;
// import org.slf4j.Logger;
// import org.slf4j.LoggerFactory;
// import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.beans.factory.annotation.Value;
// import org.springframework.boot.test.context.SpringBootTest;
// import org.springframework.data.redis.core.StringRedisTemplate;
// import org.springframework.stereotype.Component;
// import org.springframework.test.context.junit4.SpringRunner;
//
// import java.io.*;
// import java.net.HttpURLConnection;
// import java.net.URL;
// import java.net.URLConnection;
// import java.nio.channels.FileChannel;
// import java.nio.charset.StandardCharsets;
// import java.security.MessageDigest;
// import java.text.SimpleDateFormat;
// import java.util.Date;
// import java.util.HashMap;
// import java.util.Map;
//
// /**
//  * @date 日期：2023/4/26 时间：09:57
//  * @Description: 上传文件到百度网盘
//  */
// @SpringBootTest(classes = ServiceOssApplication.class)
// @RunWith(SpringRunner.class)
// public class AutoUploadFile {
//     @Autowired
//     private StringRedisTemplate redisTemplate;
//     // 操作文件 copy, mover, rename, delete
//     String FILE_MANAGER_URL = " https://pan.baidu.com/rest/2.0/xpan/file";
//     // 预上传
//     String GET_READY_FILE_URL = "https://pan.baidu.com/rest/2.0/xpan/file";
//     // 分片上传
//     String SLICING_UPLOAD_FILE_URL = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2";
//     // 下载文件
//     String DOWN_LOUE_URL = "https://pan.baidu.com/rest/2.0/xpan/multimedia";
//     // 文件搜索
//     String FILE_SEARCH = "https://pan.baidu.com/rest/2.0/xpan/file?method=search";
//     Logger logger = LoggerFactory.getLogger(getClass());
//     // 失败重试计数器
//     int num = 0;
//     // 分片大小
//     @Value("${Constant.UNIT}")
//     Integer UNIT;
//
//     @Value("${Constant.APP_ID}")
//     String APP_ID;
//     @Value("${Constant.APP_NAME}")
//     String APP_NAME;
//     @Value("${Constant.APP_KEY}")
//     String APP_KEY;
//     @Value("${Constant.SECRET_KEY}")
//     String SECRET_KEY;
//     String ATOKEN;
//
//
//     @Value("${Constant.filePath}")
//     String filePath;
//     String fileName;
//
//     // public static void main(String[] args) throws Exception {
//     //     AutoUploadFile autoUploadFile = new AutoUploadFile();
//     //     autoUploadFile.save();
//     // }
//     /*
//      * 自动刷新token
//      * token每月过期一次
//      * 通过定时任务每月刷新一次*/
//     // @Scheduled(cron = "${scheduling.getAtoken}")
//     // public void flushToken() {
//     //     try {
//     //         Properties prop = new Properties();
//     //         String atoken1 = autoRefreshToken.getAtoken();
//     //         prop.setProperty("ATOKEN", atoken1);
//     //         FileWriter writer = new FileWriter("token.properties");
//     //         prop.store(writer, "Optional header comment");
//     //         writer.close();
//     //     } catch (Exception e) {
//     //         e.printStackTrace();
//     //     }
//     // }
//
//     /**
//      * @Description: TODO 保存文件
//      * @param: filePath 文件路径
//      * @param: fileName 文件名称
//      * return 文件下载地址
//      */
//     // @Scheduled(cron = "${scheduling.executionTime}")
//     @Test
//     public void save() throws Exception {
//         getToken();
//         Date date = new Date();
//         SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
//         String formattedDate = formatter.format(date);
//         File folder = new File(filePath);
//         File[] files = folder.listFiles();
//
//         assert files != null;
//         for (File file : files) {
//             String fileName1 = file.getName();
//             boolean contains = fileName1.contains(formattedDate);
//             if (contains) {
//                 fileName = fileName1;
//             }
//         }
//         if (fileName == null) {
//             logger.info("文件不存在 !");
//             return;
//         }
//         logger.info("正在上传文件为：" + fileName);
//
//         // 本地文件地址
//         String absoluteFilePath = filePath + fileName;
//         logger.info("本地文件地址" + absoluteFilePath);
//         // 云端文件地址
//         String cloudPath = "/apps/" + APP_NAME + "/";
//         logger.info("文件在百度网盘的存放位置" + cloudPath);
//         // 文件分片并获取md5值
//         File file = new File(absoluteFilePath);
//         File[] separate = separate(absoluteFilePath, UNIT);
//
//         StringBuilder md5s = new StringBuilder();
//         if (separate.length == 1) {
//             md5s.append(getMD5(separate[0]));
//         }
//         if (separate.length > 1) {
//             for (int i = 0; i < separate.length; i++) {
//                 md5s.append(getMD5(separate[i])).append("\",\"");
//                 logger.info("正在分片,{}{}" + separate[i].toString() + ">>>" + i);
//             }
//             String s = md5s.toString();
//             md5s = new StringBuilder(s.substring(0, md5s.length() - 3));
//         }
//
//         // 预上传
//         String precreate = precreate(cloudPath, file.length(), 0, md5s.toString());
//
//         logger.info("预上传{}" + precreate);
//         String uploadid = (String) new JSONObject(precreate).get("uploadid");
//         // 分片上传
//         String upload = upload(cloudPath, (String) new JSONObject(precreate).get("uploadid"), separate);
//         logger.info("分片上传{}" + upload);
//         // 创建文件
//         String create = create(fileName, file.length(), 0, md5s.toString(), uploadid);
//         logger.info("创建文件{}" + create);
//
//         // 删除解压后文件
//         File directory2 = new File(filePath);
//         File[] files2 = directory2.listFiles();
//         for (File file2 : files2) {
//             if (file2.isFile() && file2.getName().contains("part")) {
//                 file2.delete();
//             }
//         }
//         logger.info("解压后文件已经清除！");
//
//         ObjectMapper objectMapper = new ObjectMapper();
//         Map<String, Object> map = objectMapper.readValue(create, Map.class);
//         Integer errno = (Integer) map.get("errno");
//         if (errno != 0) {
//             // 发送失败3次后发送信息到邮箱
//             if (num == 3) {
//                 logger.info("上传出现问题，已发送邮件到>>>");
//             }
//             num++;
//             save();
//         }
//
//     }
//
//     private void getToken() {
//         ATOKEN = redisTemplate.opsForValue().get("baidu::access_token");
//         logger.info("accessToken值为>>>" + ATOKEN);
//     }
//
//
//     /**
//      * @Description: TODO 获取下载地址
//      * @param: fileName 文件名
//      */
//     public String getDownUrl(String fileName) {
//         String fileSearch = HttpUtil.get(FILE_SEARCH + "&access_token=" + ATOKEN + "&key=" + fileName);
//         JSONObject jsonObject = new JSONObject(fileSearch);
//         JSONArray list = jsonObject.getJSONArray("list");
//         JSONObject listJSONObject = list.getJSONObject(0);
//         Long fs_id = listJSONObject.getLong("fs_id");
//         String url = DOWN_LOUE_URL + "?method=filemetas&access_token=" + ATOKEN + "&fsids=[" + fs_id + "]&dlink=1";
//         String s = HttpUtil.get(url);
//         JSONObject sJsonObject = new JSONObject(s);
//         JSONArray jsonArray = sJsonObject.getJSONArray("list");
//         JSONObject jsonObjectClient = jsonArray.getJSONObject(0);
//         String dlink = jsonObjectClient.getStr("dlink");
//         return dlink;
//     }
//
//     /**
//      * @Description: TODO 创建文件
//      * @param: fileName 文件名称
//      * @param: size 文件大小 字节
//      * @param: isDir 0文件 1目录（设置为目录是 size要设置为0）
//      * @param: blockList （文件的md5值） 可以把文件分为多个，然后分批上传
//      * @return: java.lang.String
//      */
//     public String create(String fileName, Long size, Integer isDir, String blockList, String uploadId) {
//         String strURL = FILE_MANAGER_URL + "?method=create&access_token=" + ATOKEN;
//         String params = "path=" + "/apps/" + APP_NAME + "/" + fileName + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir + "&uploadid=" + uploadId + "&rtype=3";
//         return openTest(strURL, params, "POST");
//     }
//
//     /**
//      * @Description: TODO 分片上传
//      * @param: path 上传到百度网盘的地址
//      * @param: uploadid 上传的id
//      * @param: filePath 本地文件的地址
//      * @return: java.lang.String
//      */
//     public String upload(String path, String uploadid, File[] files) {
//         try {
//             for (int i = 0; i < files.length; i++) {
//                 String url = SLICING_UPLOAD_FILE_URL + "?method=upload" +
//                         "&access_token=" + ATOKEN +
//                         "&type=tmpfile&partseq=" + i +
//                         "&path=" + path +
//                         "&uploadid=" + uploadid;
//                 String s = sendFile(url, files[i]);
//                 logger.info("正在上传分片文件{}{}" + s + i);
//             }
//             return path;
//         } catch (Exception e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
//
//
//     /**
//      * @Description: TODO 预上传
//      * @param: cloudPath 云端路径
//      * @param: size 文件大小 字节
//      * @param: isDir 0文件 1目录（设置为目录是 size要设置为0）
//      * @param: blockList （文件的md5值） 可以把文件分为多个，然后分批上传
//      * @return: java.lang.String
//      */
//     public String precreate(String cloudPath, Long size, Integer isDir, String blockList) {
//         String strURL = GET_READY_FILE_URL + "?method=precreate&access_token=" + ATOKEN;
//         String params = "path=" + cloudPath + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir;
//         return openTest(strURL, params, "POST");
//     }
//
//
//     /**
//      * @Description: TODO 获取md5值
//      * String path 文件地址
//      */
//     private final static String[] strHex = {"0", "1", "2", "3", "4", "5",
//             "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
//
//     private static String getMD5(File path) {
//         StringBuilder buffer = new StringBuilder();
//         try {
//             MessageDigest md = MessageDigest.getInstance("MD5");
//             byte[] b = md.digest(org.apache.commons.io.FileUtils.readFileToByteArray(path));
//             for (int value : b) {
//                 int d = value;
//                 if (d < 0) {
//                     d += 256;
//                 }
//                 int d1 = d / 16;
//                 int d2 = d % 16;
//                 buffer.append(strHex[d1]).append(strHex[d2]);
//             }
//             return buffer.toString();
//         } catch (Exception e) {
//             return null;
//         }
//     }
//
//
//     /**
//      * @Description: TODO
//      * @param: strURL 网址，可以是 http://aaa?bbb=1&ccc=2 拼接的
//      * @param: params 拼接的body参数也就是form表单的参数  ddd=1&eee=2
//      * @param: method 请求方式 get/post/put/delte等
//      * @return: java.lang.String
//      */
//     public String open(String strURL, String params, String method) {
//         try {
//             URL url = new URL(strURL);// 创建连接
//             HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//             connection.setDoOutput(true);
//             connection.setDoInput(true);
//             connection.setUseCaches(false);
//             connection.setInstanceFollowRedirects(true);
//             connection.setRequestMethod(method);
//             connection.setRequestProperty("Accept", "application/json");// 设置接收数据的格式
//             connection.setRequestProperty("Content-Type", "application/json");// 设置发送数据的格式
//             connection.connect();
//
//             OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);// utf-8编码
//             out.append(params);
//             out.flush();
//             out.close(); // 读取响应
//             int length = connection.getContentLength();// 获取长度
//             InputStream is = connection.getInputStream();
//             if (length != -1) {
//                 byte[] data = new byte[length];
//                 byte[] temp = new byte[512];
//                 int readLen = 0;
//                 int destPos = 0;
//                 while ((readLen = is.read(temp)) > 0) {
//                     System.arraycopy(temp, 0, data, destPos, readLen);
//                     destPos += readLen;
//                 }
//                 return new String(data, StandardCharsets.UTF_8);
//             }
//         } catch (Exception e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
//
//
//     /**
//      * 向指定 URL 发送POST方法的请求
//      *
//      * @param url   发送请求的 URL
//      * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
//      * @return 所代表远程资源的响应结果
//      */
//     public String sendFile(String url, String param, String file) {
//         if (url == null || param == null) {
//             return url;
//         }
//
//         PrintWriter out = null;
//         BufferedReader in = null;
//         String result = "";
//         try {
//             URL realUrl = new URL(url);
//             // 打开和URL之间的连接
//             URLConnection conn = realUrl.openConnection();
//             // 设置通用的请求属性
//             conn.setRequestProperty("accept", "*/*");
//             conn.setRequestProperty("connection", "Keep-Alive");
//             conn.setRequestProperty("user-agent",
//                     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
//             // 发送POST请求必须设置如下两行
//             conn.setDoOutput(true);
//             conn.setDoInput(true);
//             // 设置链接超时时间为2秒
//             conn.setConnectTimeout(1000);
//             // 设置读取超时为2秒
//             conn.setReadTimeout(1000);
//             // 获取URLConnection对象对应的输出流
//             out = new PrintWriter(conn.getOutputStream());
//             out.write(file);
//             // 发送请求参数
//             out.print(param);
//             // flush输出流的缓冲
//             out.flush();
//             // 定义BufferedReader输入流来读取URL的响应
//             in = new BufferedReader(
//                     new InputStreamReader(conn.getInputStream()));
//             String line;
//             while ((line = in.readLine()) != null) {
//                 result += line;
//             }
//         } catch (Exception e) {
//             System.out.println(e.getMessage() + "地址：" + url);
//             return null;
//         }
//         // 使用finally块来关闭输出流、输入流
//         finally {
//             try {
//                 if (out != null) {
//                     out.close();
//                 }
//                 if (in != null) {
//                     in.close();
//                 }
//             } catch (IOException ex) {
//                 System.out.println(ex.getMessage());
//                 return null;
//             }
//         }
//         return result;
//     }
//
//
//     /**
//      * @param: filePath
//      * @param: unit 单个文件大小
//      * @return: 返回文件的目录
//      */
//     public File[] separate(Object obj, Integer unit) {
//         try {
//
//             InputStream bis = null;// 输入流用于读取文件数据
//             OutputStream bos = null;// 输出流用于输出分片文件至磁盘
//             File file = null;
//             if (obj instanceof String) {
//                 file = new File((String) obj);
//             }
//             if (obj instanceof File) {
//                 file = (File) obj;
//             }
//             String filePath = file.getAbsolutePath();
//
//             File newFile = new File(filePath.substring(0, filePath.lastIndexOf("\\") + 1));
//
//             String directoryPath = newFile.getAbsolutePath();
//             long splitSize = unit * 1024 * 1024;// 单片文件大小,MB
//             if (file.length() < splitSize) {
//                 //   log.info("文件小于单个分片大小，无需分片{}", file.length());
//                 // System.out.println();
//                 logger.info("文件小于单个分片大小，无需分片{}" + file.length());
//                 return new File[]{file};
//             }
//
//             long length = file.length();
//             long splitNum = (length / splitSize);
//             if (length % splitSize != 0) {
//                 splitNum++;
//             }
//             // todo 分片
//             FileInputStream fis = new FileInputStream(filePath);
//             FileChannel inputChannel = fis.getChannel();
//             FileOutputStream fos;
//             FileChannel outputChannel;
//             File currentDirFile = new File(filePath);
//             if (!currentDirFile.exists()) {
//                 currentDirFile.mkdirs();
//             }
//             long startPoint = 0;
//             for (int i = 1; i <= (int) splitNum; i++) {
//                 String splitFileName = filePath + i;
//                 fos = new FileOutputStream(filePath + "." + i + ".part");
//                 outputChannel = fos.getChannel();
//                 inputChannel.transferTo(startPoint, splitSize, outputChannel);
//                 startPoint += splitSize;
//                 outputChannel.close();
//                 fos.close();
//             }
//             inputChannel.close();
//
//
//             logger.info("文件分片成功！");
//             // 排除被分片的文件
//             if (newFile.isDirectory()) {
//                 File[] files = newFile.listFiles();
//                 int num = 0;
//                 for (int i = 0; i < files.length; i++) {
//                     if (files[i].getName().contains("part")) {
//
//                     /*  File srcFile = FileUtil.file(files[i].getPath());
//                         //目标目录不存在程序也会帮忙创建
//                         File destFile = FileUtil.file("d://DB_test");
//                         FileUtil.move(srcFile, destFile, true);*/
//
//                         num++;
//                     }
//
//                 }
//                 File[] resultFiles = new File[num];
//                 int j = 0;
//                 for (int i = 0; i < files.length; i++) {
//                     //!files[i].equals(file)
//                     if (files[i].getName().contains("part")) {
//                         resultFiles[j] = files[i];
//                         j++;
//                     }
//                 }
//
//
//                 return resultFiles;
//             }
//
//             bos.flush();
//             bos.close();
//             bis.close();
//             return new File[0];
//         } catch (Exception e) {
//
//             logger.info("文件分片失败！");
//             e.printStackTrace();
//         }
//         return null;
//     }
//
//     // splitNum:要分几片，currentDir：分片后存放的位置，subSize：按多大分片
//     public File[] nioSpilt(Object object, int splitNum, String currentDir, double subSize) {
//         try {
//             File file = null;
//             if (object instanceof String) {
//                 file = new File((String) object);
//             }
//             if (object instanceof String) {
//                 file = (File) object;
//             }
//             FileInputStream fis = new FileInputStream(file);
//             FileChannel inputChannel = fis.getChannel();
//             FileOutputStream fos;
//             FileChannel outputChannel;
//             long splitSize = (long) subSize;
//             long startPoint = 0;
//             long endPoint = splitSize;
//             for (int i = 1; i <= splitNum; i++) {
//                 fos = new FileOutputStream(currentDir + i);
//                 outputChannel = fos.getChannel();
//                 inputChannel.transferTo(startPoint, splitSize, outputChannel);
//                 startPoint += splitSize;
//                 endPoint += splitSize;
//                 outputChannel.close();
//                 fos.close();
//             }
//             inputChannel.close();
//             fis.close();
//             File newFile = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("\\") + 1));
//             if (newFile.isDirectory()) {
//                 return newFile.listFiles();
//             }
//         } catch (Exception e) {
//             e.printStackTrace();
//         }
//         return new File[0];
//     }
//
//     /**
//      * @Description: TODO 发送文件
//      * @param: url 发送地址
//      * @param: file 发送文件
//      * @return: java.lang.String
//      */
//     public String sendFile(String url, File file) {
//         try {
//             MultipartEntityBuilder builder = MultipartEntityBuilder.create();
//             builder.setContentType(ContentType.MULTIPART_FORM_DATA);
//             builder.addBinaryBody("file", file);
//             String body = "";
//             // 创建httpclient对象
//             CloseableHttpClient client = HttpClients.createDefault();
//             // 创建post方式请求对象
//             HttpPost httpPost = new HttpPost(url);
//             // 设置请求参数
//             HttpEntity httpEntity = builder.build();
//             httpPost.setEntity(httpEntity);
//
//
//             // 执行请求操作，并拿到结果（同步阻塞）
//             CloseableHttpResponse response = client.execute(httpPost);
//
//             // 获取结果实体
//             HttpEntity entity = response.getEntity();
//             if (entity != null) {
//                 // 按指定编码转换结果实体为String类型
//                 body = EntityUtils.toString(entity, "utf-8");
//             }
//             EntityUtils.consume(entity);
//             // 释放链接
//
//             response.close();
//             return body;
//         } catch (Exception e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
//
//
//     public String openTest(String strURL, String params, String method) {
//         logger.info(strURL);
//         logger.info(params);
//         StringBuffer response = null;
//         try {
//             URL url = new URL(strURL);// 创建连接
//             HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
//             httpConn.setRequestMethod("POST");
//             httpConn.setRequestProperty("User-Agent", "pan.baidu.com");
//             httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//             httpConn.setDoOutput(true);
//
//             OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
//             writer.write(params);
//
//             writer.flush();
//             writer.close();
//             httpConn.getOutputStream().close();
//
//             int responseCode = httpConn.getResponseCode();
//             System.out.println("Response Code : " + responseCode);
//             BufferedReader in = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
//             String inputLine;
//             response = new StringBuffer();
//             while ((inputLine = in.readLine()) != null) {
//                 response.append(inputLine);
//             }
//
//             in.close();
//             System.out.println(response.toString());
//         } catch (Exception e) {
//             System.out.println(e);
//         }
//         return response == null ? null : response.toString();
//     }
//
//     /**
//      * 分片上传
//      *
//      * @param file     上传的文件内容
//      * @param path     上传后使用的文件绝对路径，需要urlencode
//      * @param uploadid precreate接口下发的uploadid
//      * @param partseq  文件分片的位置序号，从0开始，参考precreate接口返回的block_list
//      * @return
//      */
//     public String slicingUpload(String file, String path, String uploadid, int partseq) throws Exception {
//
//         // todo
//         // 请求url
//         String url = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?" + "&app_id=" + APP_ID + "&access_token=" + ATOKEN + "&method=upload&type=tmpfile" + "&path=" + path + "&uploadid=" + uploadid + "&partseq=" + partseq;
//         // "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?method=upload&access_token=xxx&path=/apps/test/test.jpg&type=tmpfile&uploadid=N1-NjEuMTM1LjE2OS44NDoxNTk2MTExNTczOjQ5MTMzMjgwNjk3MDYxODg3MzQ=&partseq=0"
//         Map<String, Object> map = new HashMap<>();
//         map.put("file", new File(file));
//         try {
//
//             String result = HttpUtil.post(url, map);
//
//             System.out.println(result);
//             return result;
//
//         } catch (Exception e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
//
//     /**
//      * 创建文件 用于将多个分片合并成一个文件，完成文件的上传。
//      * 备注：可以使用该接口创建文件夹。
//      *
//      * @return
//      */
//     public String folderMerge(String filePath, Long size, String blockList, String uploadid) {
//         // 百度网盘token
//         String accessToken = ATOKEN;
//         // 请求url
//         String url = "https://pan.baidu.com/rest/2.0/xpan/file?method=create" + "&access_token=" + accessToken;
//
//         try {
//             Map<String, Object> map = new HashMap<>();
//             // todo
//             map.put("path", filePath);
//             map.put("size", size);
//             map.put("isdir", 0);
//             map.put("block_list", blockList);
//             map.put("uploadid", uploadid);
//             String result = HttpUtil.post(url, map);
//             System.out.println(result);
//             return result;
//         } catch (Exception e) {
//             e.printStackTrace();
//         }
//         return null;
//     }
//
//
// }
//
